From 2fe0c2b4b23e526801ade3d54dedb578af04307c Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Thu, 5 Mar 2026 13:04:37 +0100 Subject: [PATCH] messageTray: Avoid notification double destruction after activation The activation handler of a notification may indirectly have already destroyed it before `activate()` continues and tries to destroy it. This happened for example in the `FdoNotificationDaemon` activation handler when no default actions are specified, which ends up calling `destroyNonResidentNotifications()`. Another case where this could happen is the `WindowAttentionHandler` which activates the window and upon activation of the window destroys the entire notification source, which also destroys the notification. Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5421 Part-of: --- js/ui/messageTray.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index d4f7cded8..e593d0da7 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -467,8 +467,14 @@ export class Notification extends GObject.Object { } activate() { + console.assert(!this._destroyed, 'Activating a destroyed notification'); + this.emit('activated'); + // Avoid double destruction after activation + if (this._destroyed) + return; + // We don't hide a resident notification when the user invokes one of its actions, // because it is common for such notifications to update themselves with new // information based on the action. We'd like to display the updated information @@ -482,6 +488,8 @@ export class Notification extends GObject.Object { destroy(reason = NotificationDestroyedReason.DISMISSED) { this.emit('destroy', reason); + this._destroyed = true; + if (this._updateDatetimeId) GLib.source_remove(this._updateDatetimeId); delete this._updateDatetimeId; -- 2.39.5